home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SAMPLES / STAR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-26  |  6.8 KB  |  331 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include <GL/glut.h>
  30.  
  31.  
  32. #ifndef PI
  33. #define PI 3.141592657
  34. #endif
  35.  
  36. enum {
  37.     NORMAL = 0,
  38.     WEIRD = 1
  39. };
  40.  
  41. enum {
  42.     STREAK = 0,
  43.     CIRCLE = 1
  44. };
  45.  
  46. #define MAXSTARS 400
  47. #define MAXPOS 10000
  48. #define MAXWARP 10
  49. #define MAXANGLES 6000
  50.  
  51.  
  52. typedef struct _starRec {
  53.     GLint type;
  54.     float x[2], y[2], z[2];
  55.     float offsetX, offsetY, offsetR, rotation;
  56. } starRec;
  57.  
  58.  
  59. GLenum doubleBuffer;
  60. GLint windW, windH;
  61.  
  62. GLenum flag = NORMAL;
  63. GLint starCount = MAXSTARS / 2;
  64. float speed = 1.0;
  65. GLint nitro = 0;
  66. starRec stars[MAXSTARS];
  67. float sinTable[MAXANGLES];
  68.  
  69.  
  70. float Sin(float angle)
  71. {
  72.  
  73.     return (sinTable[(GLint)angle]);
  74. }
  75.  
  76. float Cos(float angle)
  77. {
  78.  
  79.     return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
  80. }
  81.  
  82. void NewStar(GLint n, GLint d)
  83. {
  84.  
  85.     if (rand()%4 == 0) {
  86.     stars[n].type = CIRCLE;
  87.     } else {
  88.     stars[n].type = STREAK;
  89.     }
  90.     stars[n].x[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  91.     stars[n].y[0] = (float)(rand() % MAXPOS - MAXPOS / 2);
  92.     stars[n].z[0] = (float)(rand() % MAXPOS + d);
  93.     if (rand()%4 == 0 && flag == WEIRD) {
  94.     stars[n].offsetX = (float)(rand() % 100 - 100 / 2);
  95.     stars[n].offsetY = (float)(rand() % 100 - 100 / 2);
  96.     stars[n].offsetR = (float)(rand() % 25 - 25 / 2);
  97.     } else {
  98.     stars[n].offsetX = 0.0;
  99.     stars[n].offsetY = 0.0;
  100.     stars[n].offsetR = 0.0;
  101.     }
  102. }
  103.  
  104. void RotatePoint(float *x, float *y, float rotation)
  105. {
  106.     float tmpX, tmpY;
  107.  
  108.     tmpX = *x * Cos(rotation) - *y * Sin(rotation);
  109.     tmpY = *y * Cos(rotation) + *x * Sin(rotation);
  110.     *x = tmpX;
  111.     *y = tmpY;
  112. }
  113.  
  114. void MoveStars(void)
  115. {
  116.     float offset;
  117.     GLint n;
  118.  
  119.     offset = speed * 60.0;
  120.  
  121.     for (n = 0; n < starCount; n++) {
  122.     stars[n].x[1] = stars[n].x[0];
  123.     stars[n].y[1] = stars[n].y[0];
  124.     stars[n].z[1] = stars[n].z[0];
  125.     stars[n].x[0] += stars[n].offsetX;
  126.     stars[n].y[0] += stars[n].offsetY;
  127.     stars[n].z[0] -= offset;
  128.         stars[n].rotation += stars[n].offsetR;
  129.         if (stars[n].rotation > MAXANGLES) {
  130.             stars[n].rotation = 0.0;
  131.     }
  132.     }
  133. }
  134.  
  135. GLenum StarPoint(GLint n)
  136. {
  137.     float x0, y0, x1, y1, width;
  138.     GLint i;
  139.  
  140.     x0 = stars[n].x[0] * windW / stars[n].z[0];
  141.     y0 = stars[n].y[0] * windH / stars[n].z[0];
  142.     RotatePoint(&x0, &y0, stars[n].rotation);
  143.     x0 += windW / 2.0;
  144.     y0 += windH / 2.0;
  145.  
  146.     if (x0 >= 0.0 && x0 < windW && y0 >= 0.0 && y0 < windH) {
  147.     if (stars[n].type == STREAK) {
  148.         x1 = stars[n].x[1] * windW / stars[n].z[1];
  149.         y1 = stars[n].y[1] * windH / stars[n].z[1];
  150.         RotatePoint(&x1, &y1, stars[n].rotation);
  151.         x1 += windW / 2.0;
  152.         y1 += windH / 2.0;
  153.  
  154.         glLineWidth(MAXPOS/100.0/stars[n].z[0]+1.0);
  155.         glColor3f(1.0, (MAXWARP-speed)/MAXWARP, (MAXWARP-speed)/MAXWARP);
  156.         if (fabs(x0-x1) < 1.0 && fabs(y0-y1) < 1.0) {
  157.         glBegin(GL_POINTS);
  158.             glVertex2f(x0, y0);
  159.         glEnd();
  160.         } else {
  161.         glBegin(GL_LINES);
  162.             glVertex2f(x0, y0);
  163.             glVertex2f(x1, y1);
  164.         glEnd();
  165.         }
  166.     } else {
  167.         width = MAXPOS / 10.0 / stars[n].z[0] + 1.0;
  168.         glColor3f(1.0, 0.0, 0.0);
  169.         glBegin(GL_POLYGON);
  170.         for (i = 0; i < 8; i++) {
  171.             float x = x0 + width * Cos((float)i*MAXANGLES/8.0);
  172.             float y = y0 + width * Sin((float)i*MAXANGLES/8.0);
  173.             glVertex2f(x, y);
  174.         };
  175.         glEnd();
  176.     }
  177.     return GL_TRUE;
  178.     } else {
  179.     return GL_FALSE;
  180.     }
  181. }
  182.  
  183. void ShowStars(void)
  184. {
  185.     GLint n;
  186.  
  187.     glClear(GL_COLOR_BUFFER_BIT);
  188.  
  189.     for (n = 0; n < starCount; n++) {
  190.     if (stars[n].z[0] > speed || (stars[n].z[0] > 0.0 && speed < MAXWARP)) {
  191.         if (StarPoint(n) == GL_FALSE) {
  192.         NewStar(n, MAXPOS);
  193.         }
  194.     } else {
  195.         NewStar(n, MAXPOS);
  196.     }
  197.     }
  198. }
  199.  
  200. static void Init(void)
  201. {
  202.     float angle;
  203.     GLint n;
  204.  
  205.     srand((unsigned int) glutGet(GLUT_ELAPSED_TIME) );
  206.  
  207.     for (n = 0; n < MAXSTARS; n++) {
  208.     NewStar(n, 100);
  209.     }
  210.  
  211.     angle = 0.0;
  212.     for (n = 0; n < MAXANGLES ; n++) {
  213.     sinTable[n] = sin(angle);
  214.         angle += PI / (MAXANGLES / 2.0);
  215.     }
  216.  
  217.     glClearColor(0.0, 0.0, 0.0, 0.0);
  218.  
  219.     glDisable(GL_DITHER);
  220. }
  221.  
  222. void Reshape(int width, int height)
  223. {
  224.  
  225.     windW = (GLint)width;
  226.     windH = (GLint)height;
  227.  
  228.     glViewport(0, 0, windW, windH);
  229.  
  230.     glMatrixMode(GL_PROJECTION);
  231.     glLoadIdentity();
  232.     gluOrtho2D(-0.5, windW+0.5, -0.5, windH+0.5);
  233.     glMatrixMode(GL_MODELVIEW);
  234. }
  235.  
  236. static void Key(unsigned char key, int x, int y)
  237. {
  238.  
  239.     switch (key) {
  240.       case 27:
  241.     exit(1);
  242.       case 32:
  243.     flag = (flag == NORMAL) ? WEIRD : NORMAL;
  244.     break;
  245.       case 't':
  246.     nitro = 1;
  247.     break;
  248.       default:
  249.     return;
  250.     }
  251. }
  252.  
  253. void Draw(void)
  254. {
  255.  
  256.     MoveStars();
  257.     ShowStars();
  258.     if (nitro > 0) {
  259.     speed = (float)(nitro / 10) + 1.0;
  260.     if (speed > MAXWARP) {
  261.         speed = MAXWARP;
  262.     }
  263.     if (++nitro > MAXWARP*10) {
  264.         nitro = -nitro;
  265.     }
  266.     } else if (nitro < 0) {
  267.     nitro++;
  268.     speed = (float)(-nitro / 10) + 1.0;
  269.     if (speed > MAXWARP) {
  270.         speed = MAXWARP;
  271.     }
  272.     }
  273.  
  274.     glFlush();
  275.     if (doubleBuffer) {
  276.     glutSwapBuffers();
  277.     }
  278. }
  279.  
  280. static GLenum Args(int argc, char **argv)
  281. {
  282.     GLint i;
  283.  
  284.     doubleBuffer = GL_FALSE;
  285.  
  286.     for (i = 1; i < argc; i++) {
  287.     if (strcmp(argv[i], "-sb") == 0) {
  288.         doubleBuffer = GL_FALSE;
  289.     } else if (strcmp(argv[i], "-db") == 0) {
  290.         doubleBuffer = GL_TRUE;
  291.     }
  292.     }
  293.     return GL_TRUE;
  294. }
  295.  
  296. void GLUTCALLBACK glut_post_redisplay_p(void)
  297. {
  298.       glutPostRedisplay();
  299. }
  300.  
  301. void main(int argc, char **argv)
  302. {
  303.     GLenum type;
  304.  
  305.     glutInit(&argc, argv);
  306.  
  307.     if (Args(argc, argv) == GL_FALSE) {
  308.     exit(1);
  309.     }
  310.  
  311.     windW = 300;
  312.     windH = 300;
  313.     glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
  314.  
  315.     type = GLUT_RGB;
  316.     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  317.     glutInitDisplayMode(type);
  318.  
  319.     if (glutCreateWindow("Stars") == GL_FALSE) {
  320.     exit(1);
  321.     }
  322.  
  323.     Init();
  324.  
  325.     glutReshapeFunc(Reshape);
  326.     glutKeyboardFunc(Key);
  327.     glutDisplayFunc(Draw);
  328.     glutIdleFunc(glut_post_redisplay_p);
  329.     glutMainLoop();
  330. }
  331.